﻿using Microsoft.Practices.Prism.StoreApps;
using Microsoft.Practices.Prism.StoreApps.Interfaces;
using Sumc.Client.ModernUI.Common;
using Sumc.Client.ModernUI.Helpers;
using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.Windows.Input;

namespace Sumc.Client.ModernUI.ViewModels
{
    public abstract class BaseViewModel : ViewModel
    {
        protected ICommand goToHome;
        protected ICommand goBack;
        protected ICommand openSearchPane;
        protected ICommand showFlyout;
        protected bool loadingData;
        protected bool isAuthenticated;
        protected Func<Task> callBack;
        protected readonly INavigationService navigationService;
        protected readonly IAlertMessageService alertMessageService;
        protected readonly IFlyoutService flyoutService;
        protected readonly ISearchPaneService searchPaneService;

        public BaseViewModel(INavigationService navigationService,
            IAlertMessageService alertMessageService,
            IFlyoutService flyoutService,
            ISearchPaneService searchPaneService)
        {
            this.searchPaneService = searchPaneService;
            this.flyoutService = flyoutService;
            this.alertMessageService = alertMessageService;
            this.navigationService = navigationService;
            this.searchPaneService.ShowOnKeyboardInput(true);
            this.IsAuthenticated = true;
        }

        public ICommand ShowFlyout
        {
            get
            {
                if (this.showFlyout == null)
                {
                    this.showFlyout = new DelegateCommand(this.ShowFlyoutHandler);
                }

                return this.showFlyout;
            }
        }

        public ICommand OpenSearchPane
        {
            get
            {
                if (this.openSearchPane == null)
                {
                    this.openSearchPane = new DelegateCommand(() => this.searchPaneService.Show());
                }

                return this.openSearchPane;
            }
        }

        public ICommand GoToHome
        {
            get
            {
                if (this.goToHome == null)
                {
                    this.goToHome = new DelegateCommand(() => this.navigationService.Navigate(Constants.HomePage, null));
                }

                return this.goToHome;
            }
        }

        public ICommand GoBack
        {
            get
            {
                if (this.goBack == null)
                {
                    this.goBack = new DelegateCommand(this.navigationService.GoBack, this.navigationService.CanGoBack);
                }

                return this.goBack;
            }
        }

        public bool IsAuthenticated
        {
            get
            {
                return this.isAuthenticated;
            }

            set
            {
                this.SetProperty(ref this.isAuthenticated, value);
            }
        }

        public bool LoadingData
        {
            get
            {
                return this.loadingData;
            }

            set
            {
                this.SetProperty(ref this.loadingData, value);
            }
        }

        protected async virtual void LoadData(Func<Task> action)
        {
            bool isErrorPresent = false;
            try
            {
                this.IsAuthenticated = true;
                this.LoadingData = true;
                await action();
            }
            catch (HttpRequestException hrex)
            {
                if (hrex.Message.Contains("417"))
                {
                    this.IsAuthenticated = false;
                    this.callBack = action;
                }
                else
                {
                    isErrorPresent = true;
                }
            }
            finally
            {
                this.LoadingData = false;
            }

            if (isErrorPresent)
            {
                this.ShowAlertMessage();
            }
        }
  
        private async void ShowAlertMessage()
        {
            var isShown = false;
            while (!isShown)
            {
                try
                {
                    await this.alertMessageService.ShowAsync("Моля, проверете вашата връзка с интернет.", "Възникна проблем при връзката с услугите");
                    isShown = true;
                }
                catch { }

                if (!isShown)
                {
                    // Other system alert is shown, so we wait to be closed.
                    await Task.Delay(5000);
                }
            }
        }

        private void ShowFlyoutHandler()
        {
            this.flyoutService.ShowFlyout(
                Constants.CaptchaFlyout, null,
                () => this.LoadData(this.callBack));
        }
    }
}
